package com.sun.future;

import java.util.concurrent.*;

public class CookingWaterBoiledFishDemo {

    // 使用自定义线程池。注意：实际生产环境中应根据需求合理配置线程池参数。
    private static final ExecutorService taskExecutor = Executors.newFixedThreadPool(1);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("开始准备水煮鱼...");

        // 1. 异步任务：买鱼（包含多个步骤）
        CompletableFuture<Long> buyFishFuture = buyFishAsync();
        // 2. 异步任务：烧水
        CompletableFuture<Long> boilWaterFuture = boilWaterAsync();
        // 3. 异步任务：买调料
        CompletableFuture<Long> buySeasoningFuture = buySeasoningAsync();

        // 编排任务：等待买鱼、烧水、买调料全部完成，然后开始做鱼
//        CompletableFuture<Void> prepareIngredientsFuture = CompletableFuture.allOf(buyFishFuture, boilWaterFuture, buySeasoningFuture);
//
//        CompletableFuture<String> cookFishFuture = prepareIngredientsFuture.thenApplyAsync(v -> {
//            System.out.println("[" + Thread.currentThread().getName() + "] 所有材料准备完毕，开始做鱼！");
//            try {
//                // 模拟做鱼耗时
//                TimeUnit.SECONDS.sleep(4);
//            } catch (InterruptedException e) {
//                Thread.currentThread().interrupt();
//                throw new RuntimeException(e);
//            }
//            return "美味的水煮鱼做好了！";
//        }, taskExecutor);

        CompletableFuture<String> stringCompletableFuture = buyFishFuture
                .thenCompose(buyFishTime -> {
                    // 买鱼完成后执行买调料
                    return buySeasoningFuture;
                })
                .thenCompose(buySeasoningTime -> {
                    // 买调料完成后执行烧水
                    return boilWaterFuture;
                })
                .thenCompose(boilWaterTime -> {
                    // 所有准备工作完成后开始做鱼
                    return CompletableFuture.supplyAsync(() -> {
                        // 做鱼逻辑
                        System.out.println("[" + Thread.currentThread().getName() + "] 所有材料准备完毕，开始做鱼！");
                        try {
                            // 模拟做鱼耗时
                            TimeUnit.SECONDS.sleep(4);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            throw new RuntimeException(e);
                        }
                        return "美味的水煮鱼做好了！";
                    }, taskExecutor);
                });

        // 等待最终结果
        String finalDish = stringCompletableFuture.get();
        System.out.println(finalDish);

        // 关闭线程池
        taskExecutor.shutdown();
    }

    private static CompletableFuture<Long> buyFishAsync() {
        return CompletableFuture.supplyAsync(() -> {
            long startTime = System.currentTimeMillis();
            System.out.println("[" + Thread.currentThread().getName() + "] 买鱼郎出发去市场...");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("[" + Thread.currentThread().getName() + "] 到达市场，开始挑鱼...");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("[" + Thread.currentThread().getName() + "] 挑好鱼，回家...");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            long totalTime = System.currentTimeMillis() - startTime;
            System.out.println("[" + Thread.currentThread().getName() + "] 买鱼完成，耗时" + totalTime + "毫秒");
            return totalTime;
        }, taskExecutor);
    }

    private static CompletableFuture<Long> boilWaterAsync() {
        return CompletableFuture.supplyAsync(() -> {
            long startTime = System.currentTimeMillis();
            System.out.println("[" + Thread.currentThread().getName() + "] 开始烧水...");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            long totalTime = System.currentTimeMillis() - startTime;
            System.out.println("[" + Thread.currentThread().getName() + "] 水烧开了，耗时" + totalTime + "毫秒");
            return totalTime;
        }, taskExecutor);
    }

    private static CompletableFuture<Long> buySeasoningAsync() {
        return CompletableFuture.supplyAsync(() -> {
            long startTime = System.currentTimeMillis();
            System.out.println("[" + Thread.currentThread().getName() + "] 开始买调料...");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            long totalTime = System.currentTimeMillis() - startTime;
            System.out.println("[" + Thread.currentThread().getName() + "] 调料买好了，耗时" + totalTime + "毫秒");
            return totalTime;
        }, taskExecutor);
    }

}
